#ifndef STORAGE_PAGE_H
#define STORAGE_PAGE_H 1

#include <stdint.h>
#include <unistd.h>

#include <common/macro/build.h>

typedef uint16_t page_size_t;
typedef uint16_t page_itemcount_t;

typedef enum page_type_e {
	PAGE_ANY,    /* Blank page, no type */
	PAGE_LEASE,  /* Page is leased, should only appear in FSM */

	PAGE_TUPLE,
	PAGE_BLOB,
	PAGE_INDEX,
} page_type_e;

/* Forward declarations. */
typedef struct page_tuple_t page_tuple_t;
typedef struct page_blob_t page_blob_t;
typedef struct page_index_t page_index_t;

typedef struct page_t {
	page_type_e type;
	page_size_t size;
	
	page_size_t freespace;

	union {
		page_tuple_t *tuple;
		page_blob_t *blob;
		page_index_t *index;
	};

	char *raw;
} page_t;

API_LIBLOCAL page_t *page_new(page_type_e, page_size_t);
API_LIBLOCAL void page_set_empty(page_t *);
API_LIBLOCAL inline char page_type_to_char(page_type_e);
API_LIBLOCAL inline page_type_e page_char_to_type(char);
API_LIBLOCAL int page_serialize(page_t *, char *, ssize_t);
API_LIBLOCAL int page_deserialize(page_t **, char *, ssize_t);
API_LIBLOCAL inline void page_set_freespace(page_t *, page_size_t);
API_LIBLOCAL inline void page_decrease_freespace(page_t *, page_size_t);
API_LIBLOCAL inline void page_increase_freespace(page_t *, page_size_t);
API_LIBLOCAL inline page_size_t page_get_freespace(page_t *);
API_LIBLOCAL void page_destroy(page_t *);

#endif
